/**
 * 
 */
package zeroj.web.view;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import zeroj.web.dispatch.Dispatcher;
import zeroj.web.view.config.ConfigFactory;
import zeroj.web.view.config.DefaultConfigFactory;
import zeroj.web.view.config.PropertyConfigFactory;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

/**
 * @author LYL(lylsir at gmail dot com)
 * 
 * @since 1.0
 *
 * 2008-9-18
 */
public final class FreemarkerView {

	private static final Log log = LogFactory.getLog(FreemarkerView.class);
	
	private ServletContext  servletContext;
	private Configuration configuration;
	private ConfigFactory viewConfig;
	
	public FreemarkerView() {
		
	}
	public FreemarkerView(ServletContext servletContext) {
		this.servletContext = servletContext;
	}
	public ConfigFactory getViewConfig() {
		return viewConfig;
	}
	public void init() {
		
		initConfiguation();
	}
	public void display(String templateName) throws IOException, ServletException {
		
		Template template = getTemplate(templateName);
		Map<String, Object> root = new HashMap<String, Object>();
		Dispatcher.getResponse().setContentType("text/html; ; charset=utf-8");
		try {
			template.process(root, Dispatcher.getResponse().getWriter());
		} catch (TemplateException e) {
			log.warn("template exception", e);
			throw new ServletException("template exception", e);
		}
	}
	/**
	 * 可以供外部应用调用取得自定义模板文件
	 * 
	 * @param templateName
	 * @return
	 * @throws IOException
	 */
	public Template getTemplate(String templateName) throws IOException {
		
		return configuration.getTemplate(templateName);
	}
	private void initConfiguation() {
		
		configuration = new Configuration();
		loadViewConfig();
		if(servletContext != null)
			configuration.setServletContextForTemplateLoading(servletContext, viewConfig.getTemplatePath());
		else
			configuration.setClassForTemplateLoading(FreemarkerView.class, viewConfig.getTemplatePath());
		configuration.setSharedVariable("url", new UrlDirective());
		try {
			if(viewConfig.getStorageKey() != null)
				configuration.setSetting(Configuration.CACHE_STORAGE_KEY, viewConfig.getStorageKey());
		} catch(TemplateException te) {
			log.warn("init configuration", te);
		}
	}
	
	private void loadViewConfig() {
		
		viewConfig = new PropertyConfigFactory();
		if(! ((PropertyConfigFactory)viewConfig).init())
			viewConfig = new DefaultConfigFactory();
	}
	
}
